package com.symaster.gameengine.test;

import org.lwjgl.*;
import org.lwjgl.glfw.*;
import org.lwjgl.opengl.*;
import org.lwjgl.system.*;
import org.lwjgl.stb.STBImage;

import java.nio.*;
import java.nio.file.*;
import java.nio.ByteBuffer;

import static org.lwjgl.glfw.Callbacks.*;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.system.MemoryStack.*;
import static org.lwjgl.system.MemoryUtil.*;

public class TextureExample {

    private long window;

    public static void main(String[] args) {
        new TextureExample().run();
    }

    public void run() {
        System.out.println("LWJGL Version " + Version.getVersion() + "!");

        init();
        loop();

        glfwFreeCallbacks(window);
        glfwDestroyWindow(window);

        glfwTerminate();
        glfwSetErrorCallback(null).free();
    }

    private void init() {
        GLFWErrorCallback.createPrint(System.err).set();

        if (!glfwInit()) {
            throw new IllegalStateException("Unable to initialize GLFW");
        }

        glfwDefaultWindowHints();
        glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
        glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);

        window = glfwCreateWindow(800, 600, "Hello LWJGL", NULL, NULL);
        if (window == NULL) {
            throw new RuntimeException("Failed to create the GLFW window");
        }

        glfwMakeContextCurrent(window);
        glfwSwapInterval(1);
        glfwShowWindow(window);


        GL.createCapabilities();
    }

    private void loop() {
        // 设置背景色
        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

        // 加载图片并生成纹理
        int textureID = loadTexture("C:\\Users\\18790\\Pictures\\3767cb5b-02da-4b3e-9895-1371ab73283c.jpg");

        glEnable(GL_TEXTURE_2D);

        while (!glfwWindowShouldClose(window)) {
            // glViewport(0,0, );
            // glViewport(0,0, 200, 200);
            // glViewport(0,0, 100, 100);

            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

            glBindTexture(GL_TEXTURE_2D, textureID);

            // 开始绘制一个四边形并应用纹理
            glBegin(GL_QUADS);
            glTexCoord2f(0, 0); glVertex2f(-1f, -1f); // 左下角
            glTexCoord2f(1, 0); glVertex2f( 1f, -1f); // 右下角
            glTexCoord2f(1, 1); glVertex2f( 1f,  1f); // 右上角
            glTexCoord2f(0, 1); glVertex2f(-1f,  1f); // 左上角
            glEnd();

            glfwSwapBuffers(window);
            glfwPollEvents();
        }
    }

    private int loadTexture(String filePath) {
        ByteBuffer image;
        int width, height;

        try (MemoryStack stack = stackPush()) {
            IntBuffer w = stack.mallocInt(1);
            IntBuffer h = stack.mallocInt(1);
            IntBuffer channels = stack.mallocInt(1);

            image = STBImage.stbi_load(filePath, w, h, channels, 4);
            if (image == null) {
                throw new RuntimeException("Failed to load a texture file!" + System.lineSeparator() + STBImage.stbi_failure_reason());
            }

            width = w.get();
            height = h.get();
        }

        int textureID = glGenTextures();
        glBindTexture(GL_TEXTURE_2D, textureID);

        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

        STBImage.stbi_image_free(image);

        return textureID;
    }
}
